package com.imooc.uaa.validation;

import com.imooc.uaa.annotation.ValidPassword;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.passay.*;
import org.passay.spring.SpringMessageResolver;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.List;

@RequiredArgsConstructor
public class PasswordConstraintValidator implements ConstraintValidator<ValidPassword, String> {

    private final SpringMessageResolver springMessageResolver;

    @Override
    public void initialize(ValidPassword constraintAnnotation) {

    }

    @Override
    public boolean isValid(String password, ConstraintValidatorContext context) {
        val validator = new PasswordValidator(springMessageResolver, Arrays.asList(
                // 长度必须在8到30个字符之间
                new LengthRule(8, 30),
                // 必须有一个大写字母
                new CharacterRule(EnglishCharacterData.UpperCase, 1),
                // 必须又一个小写字母
                new CharacterRule(EnglishCharacterData.LowerCase, 1),
                // 必须有一个特殊字符
                new CharacterRule(EnglishCharacterData.Special, 1),
                // 不能有5个连续的字母顺序
                new IllegalSequenceRule(EnglishSequenceData.Alphabetical, 5, false),
                // 不能有5个连续的数字顺序
                new IllegalSequenceRule(EnglishSequenceData.Numerical, 5, false),
                // 不能有5连续键盘顺序
                new IllegalSequenceRule(EnglishSequenceData.USQwerty, 5, false),
                // 不能有空格
                new WhitespaceRule()
        ));
        RuleResult ruleResult = validator.validate(new PasswordData(password));
        // 禁用原有的 messages
        context.disableDefaultConstraintViolation();
        // 使用 passay 的 SpringMessageResoler
        List<String> messages = validator.getMessages(ruleResult);
        context.buildConstraintViolationWithTemplate(String.join(",", messages))
                .addConstraintViolation();
        return ruleResult.isValid();
    }
}
